package com.yuncheng.oaApi.lcService;


import com.yuncheng.oaApi.vo.AgentVo;
import com.yuncheng.oaApi.vo.OaFlowVo;
import com.yuncheng.oaApi.vo.Result;
import org.apache.commons.collections.CollectionUtils;
import com.yuncheng.oaApi.utils.GetUuIdUtils;;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yuncheng.oaApi.constant.OaCommonFlowConstant;
import com.yuncheng.oaApi.constant.OaLogConstant;
import com.yuncheng.oaApi.constant.OaGwycOaFlowConstants;
import com.yuncheng.oaApi.constant.OaLgqsOaFlowConstants;
import com.yuncheng.oaApi.entity.OaGwyc;
import com.yuncheng.oaApi.entity.OaJobEntity;
import com.yuncheng.entity.YcSysUser;
import com.yuncheng.exception.BusinessException;
import com.yuncheng.oaApi.service.IOaGwycService;
import com.yuncheng.spcyApi.service.ISpcyLogService;
import com.yuncheng.oaApi.service.IOaSpcySqsxJobService;
import com.yuncheng.oaApi.service.IOaSysUserFgldService;
import com.yuncheng.oaApi.service.impl.OaYcSysUserServiceImpl;
import com.yuncheng.spcyApi.utils.DateConvert;
import com.yuncheng.utils.ThreadContextHelper;
import com.yuncheng.vo.*;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import utils.DateConversionUtils;
import utils.LogUtils;
import utils.ObjectToMapUtils;

import javax.annotation.Resource;
import java.lang.reflect.InvocationTargetException;
import java.util.*;

@Component(value = "oaGwycFlowService")
public class OaGwycOaFlowService extends OaFlowService {
    private static final Logger log = LoggerFactory.getLogger(OaGwycOaFlowService.class);

    @Resource
    private IOaSpcySqsxJobService spcySqsxJobService;

    @Resource
    @Lazy
    private OaGwycOaFlowConstants oaGwycFlowConstant;

    @Resource
    @Lazy
    private IOaSysUserFgldService sysUserFgldService;

    @Resource
    @Lazy
    private OaYcSysUserServiceImpl ycSysUserService;

    @Resource
    @Lazy
    private IOaGwycService oaGwycService;

    @Resource
    @Lazy
    private ISpcyLogService spcyLogService;

    public Result handleFlow(OaFlowVo oaFlowVo, OaJobEntity nowJob, String jobId, String oaid, String submitType, String opinion){

        // 当前流程任务
        if (StringUtils.isNotBlank(jobId)) {
            nowJob = spcySqsxJobService.getById(jobId);
        }

        if (nowJob == null){
            return Result.error("当前流程任务不存在，请重试");
        }

        // 提交按钮
        if (submitType.equals(OaCommonFlowConstant.SUBMIT_TYPE_SUBMIT)) {
            if (nowJob == null) {
                return Result.error("当前流程任务不存在");
            }
        }
        CurrentUserVo currentUser = ThreadContextHelper.getCurrentUser();
        if (currentUser == null){
            return Result.error("登录已失效，请重新登录");
        }

        // 流程环节处理
        Result httpResult = handleNodeName(oaFlowVo, submitType, nowJob, oaid, opinion);
        if (!httpResult.isSuccess()){
            return httpResult;
        }
        //最后一步状态标注流程结束
        /**
         * @Author: lhb
         * @Description : 是提交且 是最后一步流程
         * @DateTime:
         * @Params:
         */
        if(submitType.equals(OaCommonFlowConstant.SUBMIT_TYPE_SUBMIT) && nowJob.getFhjmc().equals(OaGwycOaFlowConstants.HJMC_BGSAP)){
            //当前流程id
            OaGwyc byId = oaGwycService.getById(oaid);
            byId.setFlczt(OaCommonFlowConstant.FLOW_LCJS);
            oaGwycService.updateById(byId);

        }

        return Result.ok("操作成功");
    }

    /**
     * @Author:
     * @Description : 退回流程
     * @DateTime:
     * @Params:
     */
    public Result getReturnUpperFlowJob(String jobid,String opinion){
        if (StringUtils.isBlank(jobid)){
            return Result.error("当前流程任务id不能为空");
        }
        OaJobEntity job = spcySqsxJobService.getById(jobid);
        if (job == null){
            return Result.error("当前流程任务不存在");
        }
        // 办理状态 - 待办
        if (StringUtils.isNotBlank(job.getFblzt()) && (job.getFblzt().equals(OaCommonFlowConstant.BLZT_DB) || job.getFblzt().equals(OaCommonFlowConstant.BLZT_TH))){
            // 待办-获取上一个环节id
            String fsyhjid = job.getFsyhjid();
            OaJobEntity syhjJob = spcySqsxJobService.getById(fsyhjid);
            if (syhjJob != null){
                syhjJob.setFthyj(opinion);
                syhjJob.setFfssj(new Date());
                syhjJob.setFblzt(OaCommonFlowConstant.BLZT_TH);
                spcySqsxJobService.updateById(syhjJob);

                spcySqsxJobService.removeById(jobid); // 删除当前流程任务待办
            }
        }
        String logNr = "退回上一环节: ";
        Map<String, Object> map = ObjectToMapUtils.objectToMap(job);
        logNr += LogUtils.MapToStringMethod(map);
        spcyLogService.addLogs(job.getFhjmc(),logNr,job.getFpid(), OaLogConstant.LOGS_SQSX_JOB, OaCommonFlowConstant.LOGS_SYS_TYPE_TH);
        return Result.ok("success");
    }

    public Result handleNodeName(OaFlowVo oaFlowVo, String submitType, OaJobEntity job, String oaId, String opinion){
        HashMap<String, Object> map = oaFlowVo.getMap();
        String dbrid = oaFlowVo.getDbrid();// 下环节待办人
        String smgflag = oaFlowVo.getSmgflag(); // 短信发送标志
        boolean isSubmit = true; // 是否提交流程
        Result res = null;

        // 保存按钮
        if (submitType.equals(OaCommonFlowConstant.SUBMIT_TYPE_SAVE)){
            updateSqsxJbxx(map,oaId,job);
        }

        // 提交按钮
        if (submitType.equals(OaCommonFlowConstant.SUBMIT_TYPE_SUBMIT)){
            updateSqsxJbxx(map,oaId,job);

            // 流程任务id
            String jobId = "";
            if (job != null){
                jobId = job.getId();
            }
            /**
            * @Author: lhb
            * @Description : 如果不是开头跳转环节，在这里写跳转环节的判断，然后设置变量接收下个环节的节点的变量 写到nextNodeName里面
            * @DateTime:
            * @Params:
            */

            // 提交流程任务,待办人是否为空，指定待办人
            if (isSubmit) {
                if (StringUtils.isBlank(dbrid)) {
                    // 提交-流程任务
                    res = this.passJob(oaId, jobId, opinion, "", "");
                } else {
                    // 提交-流程任务
                    res = this.passJob(oaId, jobId, opinion, "", dbrid);
                }
            }
            if (!res.isSuccess()){
                return res;
            }else {
                OaJobEntity nowJob = (OaJobEntity)res.getResult();
                // 接收返回的流程任务，如果返回的流程任务id不相等，发送短信
                if (nowJob != null && !jobId.equals(nowJob.getId()) && StringUtils.isNotBlank(smgflag) && smgflag.equals("是")){

                }
            }
        }

        return Result.ok("提交成功");
    }

    public Result updateSqsxJbxx(HashMap<String,Object> map, String oaid, OaJobEntity job){
        OaGwyc oldBasic = oaGwycService.getById(oaid);
        if (oldBasic == null){
            return Result.error("当前申请事项【"+oaid+"】不存在，请重试");
        }
        OaGwyc basicUpdate = null;
        basicUpdate = oldBasic;

        // 修改
        ConvertUtils.register(new DateConvert(), java.util.Date.class);
        try {
            BeanUtils.populate(basicUpdate,map);
            oaGwycService.updateById(basicUpdate);
        } catch (IllegalAccessException e) {
            log.error("出错-保存申请事项【非法访问异常】,{}",e.getMessage());
        } catch (InvocationTargetException e) {
            log.error("出错-保存申请事项【调用TargetException】,{}",e.getMessage());
        }

        String logContent = "基本信息修改: ";
        Map<String, Object> basicMap = ObjectToMapUtils.objectToMap(oldBasic);
        logContent += LogUtils.BeanModifyMsg(basicUpdate,basicMap);

        if (job == null) {
            spcyLogService.addLogs("null", logContent, oaid, OaCommonFlowConstant.LOGS_SYS_TYPE_XG, OaCommonFlowConstant.LOGS_SYS_TYPE_XG);
        }else {
            spcyLogService.addLogs(job.getFhjmc(), logContent, oaid, OaCommonFlowConstant.LOGS_SYS_TYPE_XG, OaCommonFlowConstant.LOGS_SYS_TYPE_XG);
        }

        return Result.ok("保存成功");
    }

    /**
     * 获取当前流程任务相关信息
     * @param jobid 流程任务id
     */
    public Map getJobConcernByJobId(String jobid){
        Map map = new HashMap();

        // 当前流转记录
        OaJobEntity job = spcySqsxJobService.getById(jobid);
        if (job == null){
            log.error("当前流程任务id为【{}】的流转记录不存在",jobid);
            return map;
        }
        String oaid = job.getFpid();
        if (org.apache.commons.lang3.StringUtils.isBlank(oaid)){
            log.error("当前流程任务id为【{}】的流转记录中的申请事项id为空",jobid);
            return map;
        }

        // oaid事项基本信息
        OaGwyc sqsxBasic = oaGwycService.getById(oaid);

        // 流程任务流传记录
        List<OaJobEntity> jobList = this.getJobListBySqsxId(oaid);

//        // 申请事项相关文件记录
//        List<SpcySqsxWjjl> wjjlList = busService.getWjjlListBySqsxId(oaid);

        // 申请事项的检查项目
//        List<SpcySqsxJcxm> jcxmList = getJcxmQxListBySqsxId(sqsxBasic);



        // 获取下环节待办人
        String nextNode = oaGwycFlowConstant.getNextNodeName(job.getFhjmc());
        Map nextDbr = this.getNodeDbr(oaid, nextNode,"");
        List<AgentVo> dbrListByMap = getDbrListByMap(nextDbr);

        map.put("sqsx",sqsxBasic); // 申请事项基本信息
        map.put("job",job); // 当前流转记录
        map.put("jobHistoryList",jobList); // 流程任务流传记录
//        map.put("wjjlList",wjjlList); // 申请事项-相关文件

        map.put("nextNodeDbrList",dbrListByMap); // 下环节待办人list
        map.put("nextNode",nextNode);

        return map;
    }

    /**
     * 获取申请事项-流转记录
     */
    public List<OaJobEntity> getJobListBySqsxId(String oaid){
        LambdaQueryWrapper<OaJobEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(OaJobEntity::getFlcmc, oaGwycFlowConstant.getFlowName());
        queryWrapper.eq(OaJobEntity::getFpid, oaid);
        queryWrapper.orderByAsc(OaJobEntity::getCreateTime);
        queryWrapper.orderByAsc(OaJobEntity::getFfssj);
        List<OaJobEntity> jobList = spcySqsxJobService.list(queryWrapper);

        return jobList;
    }



    //初始化任务
    public Result initJob(String oaId, CurrentUserVo currentUser){
        String nodeName = oaGwycFlowConstant.getFirstNode();
        //需要校验是否已经初始化过
        List<OaJobEntity> list = spcySqsxJobService.list(new LambdaQueryWrapper<OaJobEntity>()
                .eq(OaJobEntity::getFpid, oaId)
                .eq(OaJobEntity::getFhjmc, nodeName)
                .eq(OaJobEntity::getFlcmc, oaGwycFlowConstant.getFlowName())
        );
        if(list.size()>0){
            return Result.ok(list.get(0));

        }
        return this.initJob(oaGwycFlowConstant,oaId,currentUser);
    }

    /**
     * 提交当前环节的待办记录
     *  @param oaId  oa-id
     *  @param jobId 当前环节id
     *  @param opinion 办理意见
     */
    public Result passJob(String oaId, String jobId, String opinion,String nextNodeName,String nextNodeDbrIds){
        //处理业务表的逻辑
        Result httpResult = this.passJob(oaGwycFlowConstant, oaId, jobId, opinion, nextNodeName, nextNodeDbrIds);
        return httpResult;
    }

    /**
     *
     * @param job
     * @param currentUser
     */
    private Result doJob(OaJobEntity job, CurrentUserVo currentUser, String opinion){
        String blrId = "";
        String blr = "";
        if (currentUser != null) {
            blrId = currentUser.getId();
            blr = currentUser.getName();
        }
        if (job == null){
            return Result.error("当前流程任务不存在，请重试");
        }
        if(OaCommonFlowConstant.BLZT_YB.equals(job.getFblzt())){
            return Result.error("当前任务已提交");
        }
        if(StringUtils.isBlank(job.getFdbrid())){
            return Result.error("当前任务未指定办理人");
        }
        if(!job.getFdbrid().contains(blrId)){
            return Result.error("当前登录用户无此任务的办理权限");
        }
        // 办理方式  、多人竞争办理
        String blfs = job.getFblfs();
        if(StringUtils.isBlank(blfs)||blfs.equals(OaCommonFlowConstant.BLFS_DRJJ)){
            job.setFblr(blr);
            job.setFblsj(new Date());
            job.setFblyj(opinion);
            job.setFblzt(OaCommonFlowConstant.BLZT_YB);
            spcySqsxJobService.updateById(job);
            return Result.ok(job);
        }else if(blfs.equals(OaCommonFlowConstant.BLFS_DRXX)  || blfs.equals(OaCommonFlowConstant.BLFS_DRBX)){
            //先根据多个人线性和多人并行的逻辑获得下一办理人
            String nextBlrId ="";
            String nextBlr ="";
            if(blfs.equals(OaCommonFlowConstant.BLFS_DRXX)){
                String ydbrIds[] = job.getFydbrid().split(",");
                String ydbrs[] = job.getFydbr().split(",");
                for (int i=0;i<ydbrIds.length;i++){
                    String dbrId = ydbrIds[i];
                    //不考虑办理人id重复出现（一个人办多次）的情况
                    if(dbrId.equals(blrId)){
                        if(i+1<ydbrIds.length){
                            nextBlrId=ydbrIds[i+1];
                            nextBlr=ydbrs[i+1];
                            break;
                        }
                    }
                }
            }else{
                String dbrIds[] = job.getFdbrid().split(",");
                String dbrs[] = job.getFdbr().split(",");
                for (int i=0;i<dbrIds.length;i++){
                    String dbrId = dbrIds[i];
                    String dbr = dbrs[i];
                    //不考虑办理人id重复出现（一个人办多次）的情况
                    if(!dbrId.equals(blrId)){
                        nextBlrId=nextBlrId+(StringUtils.isBlank(nextBlrId)?"":",")+dbrId;
                        nextBlr=nextBlr+(StringUtils.isBlank(nextBlr)?"":",")+dbr;
                    }
                }
            }

            //如果存在下一办理人 就继续待办，多人办理意见用@@分隔，办理时间、办理人、意见 用|分隔
            job.setFblr(blr);
            job.setFblsj(new Date());
            String blyj=(job.getFblyj()==null?"":job.getFblyj())+(StringUtils.isBlank(job.getFblyj())?"":"@@")+ DateConversionUtils.DateToString(new Date()) +"|"+blr+"|"+ opinion;
            job.setFblyj(blyj);
            if(StringUtils.isBlank(nextBlrId)){
                job.setFblzt(OaCommonFlowConstant.BLZT_YB);
            }else{
                job.setFblzt(OaCommonFlowConstant.BLZT_DB);
                job.setFdbrid(nextBlrId);
                job.setFdbr(nextBlr);
            }
            spcySqsxJobService.updateById(job);
            return Result.ok(job);
        }
        return Result.error("待办任务未指定办理方式");
    }

    /**
     *
     * @param oaId
     * @param currentJob
     * @param currentUser
     * @param nextNodeName
     * @param nextNodeDbrIds
     * @return
     */
    public Result createNextJob(String oaId, OaJobEntity currentJob, CurrentUserVo currentUser, String nextNodeName, String nextNodeDbrIds){
        if (currentJob != null) {
            nextNodeName = getNextNodeName(currentJob.getFhjmc(), nextNodeName);
        }else {
            if (StringUtils.isBlank(nextNodeName)){
                return Result.error("下环节不能为空");
            }
        }
        if(nextNodeName.equals(OaLgqsOaFlowConstants.HJMC_LCJS)){
            OaJobEntity job = new OaJobEntity();

            return Result.ok("操作成功");
        }
        Map map = this.getNodeDbr(oaId,nextNodeName,nextNodeDbrIds);
        nextNodeDbrIds = map.get("dbrId").toString();
        String nextNodeDbrs = map.get("dbr").toString();
        if(StringUtils.isBlank(nextNodeDbrIds)){
            return Result.error("获取不到下一环节待办人");
        }
        OaJobEntity job = new OaJobEntity();
        job.setId(GetUuIdUtils.generateUuid());
        if(currentJob != null){
            job.setFsyhjid(currentJob.getId());
        }
        job.setFpid(oaId);
        job.setFhjmc(nextNodeName);
        if (currentUser != null) {
            job.setFfsrid(currentUser.getId());
            job.setFfsrmc(currentUser.getName());
        }
        job.setFfssj(new Date());

        job.setFdbrid(nextNodeDbrIds);
        job.setFdbr(nextNodeDbrs);
        job.setFydbrid(nextNodeDbrIds);
        job.setFydbr(nextNodeDbrs);

        // job.setFblfs(YpzcFlowConstant.getBlfs(nextNodeName));
        job.setFblzt(OaCommonFlowConstant.BLZT_DB);
        spcySqsxJobService.save(job);
        return Result.ok(job);
    }

    /**
     *
     * @param currentNodeName 可为空(如果为空，nextNodeName不为空)
     * @param nextNodeName 可为空(如果为空，currentNodename不为空)
     * @return
     */
    private String getNextNodeName(String  currentNodeName,String nextNodeName){
        if (StringUtils.isNotBlank(nextNodeName)){
            return nextNodeName;
        }else{
            return oaGwycFlowConstant.getNextNodeName(currentNodeName);
        }
    }

    // 获取当前环节待办人
    public Map getNodeDbr(String oaid,String nodeName, String dbrIds){
        Map map = new HashMap();
        String dbrId = "";
        String dbr = "";
        if(StringUtils.isNotBlank(dbrIds)){
            dbr = getDbrsByIds(dbrIds);
            dbrId = dbrIds;
        }else{
            // 申请
            if (nodeName.equals(OaGwycOaFlowConstants.HJMC_SQ)){
                // 本人提交
                CurrentUserVo user = ThreadContextHelper.getCurrentUser(); //当前用户信息
                if (user == null){
                    throw new BusinessException("没有登录信息");
                }
                String id = user.getId();
                String name = user.getName();
                dbrId = id;
                dbr = name;
            }
            // 科室审批
            if (nodeName.equals(OaGwycOaFlowConstants.HJMC_KSSP)){
                // 科室负责人
                OaGwyc oaids = oaGwycService.getById(oaid);
                Map kzMap = getKsfzrByDeptName(oaids.getFycbm());
                dbrId = kzMap.get("dbrId").toString();
                dbr = kzMap.get("dbr").toString();
            }
            // 申请科室分管领导审批
            if (nodeName.equals(OaGwycOaFlowConstants.HJMC_SQKSFGLDSP)){
                // 分管领导
                OaGwyc oaids = oaGwycService.getById(oaid);
                Map kzMap = getKsFgldByDeptName(oaids.getFycbm());
                dbrId = kzMap.get("dbrId").toString();
                dbr = kzMap.get("dbr").toString();
            }
            // 办公室分管领导审批
            if (nodeName.equals(OaGwycOaFlowConstants.HJMC_BGSFGLDSP)){
                // 办公室分管领导审批
                String dept="办公室";


                Map kzMap = getKsFgldByDeptName(dept);
                dbrId = kzMap.get("dbrId").toString();
                dbr = kzMap.get("dbr").toString();
            }
            //办公室安排
            if (nodeName.equals(OaGwycOaFlowConstants.HJMC_BGSAP)){
                // 办公室负责人确认
                String bgsfzr="办公室";


                Map kzMap = getKsfzrByDeptName(bgsfzr);
                dbrId = kzMap.get("dbrId").toString();
                dbr = kzMap.get("dbr").toString();
            }
        }

        map.put("dbrId",dbrId);
        map.put("dbr",dbr);
        return map;
    }

    // 获取当前环节待办人
    public Map getNodeDbr(String nodeName, String dbrIds){
        return this.getNodeDbr(null,nodeName,dbrIds);
    }

    // 根据待办人id，获取名称拼接起来
    private String getDbrsByIds(String dbrIds){
        //把待办人按id查出来  把名字拼起来
        String dbr = "";
        List<String> dbrIdsList = Arrays.asList(dbrIds.split(","));
        List<YcSysUser> sysUserList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(dbrIdsList)){
            sysUserList = ycSysUserService.listByIds(dbrIdsList);
        }

        if (CollectionUtils.isNotEmpty(sysUserList)){
            for (YcSysUser user : sysUserList){
                dbr += user.getRealname() + ",";
            }
        }

        return dbr;
    }

    // 对应科室的 科室负责人
    public Map getKsfzrByDeptName(String deptName){
        Map map = new HashMap();
        String dbrId = "";
        String dbr = "";
        List<GetKsKz> ksKzObject = new ArrayList<>();
        ksKzObject = ycSysUserService.getKsKzObject(deptName, OaCommonFlowConstant.ROLE_NAME_KZ);
        if (CollectionUtils.isNotEmpty(ksKzObject)) {
            for (GetKsKz ksKz : ksKzObject) {
                dbrId += ksKz.getId()+",";
                dbr += ksKz.getRealname()+",";
            }
        }

        map.put("dbrId",dbrId);
        map.put("dbr",dbr);
        return map;
    }

    // 获取对应科室的 分管领导
    public Map getKsFgldByDeptName(String deptName){
        Map map = new HashMap();
        String dbrId = "";
        String dbr = "";

        YcSysUser fgldUserBydept = sysUserFgldService.getFgldUserBydept(deptName);
        if (fgldUserBydept != null) {
            dbrId = fgldUserBydept.getId();
            dbr = fgldUserBydept.getRealname();
        }

        map.put("dbrId",dbrId);
        map.put("dbr",dbr);
        return map;
    }


    /**
     * 将待办人map转为List
     * @param map 待办人map
     */
    public List<AgentVo> getDbrListByMap(Map map){
        String dbrids = map.get("dbrId").toString(); // 待办人id
        String dbrs = map.get("dbr").toString(); // 待办人

        List<AgentVo> agentList = new ArrayList<>();

        if (org.apache.commons.lang3.StringUtils.isNotBlank(dbrids)) {
            String agentIds[] = dbrids.split(",");
            String agentNames[] = dbrs.split(",");

            for (int i = 0; i < agentIds.length; i++) {
                AgentVo agentVo = new AgentVo();
                agentVo.setDbrid(agentIds[i]);
                agentVo.setDbr(agentNames[i]);
                agentList.add(agentVo);
            }
        }

        return agentList;
    }




}
